#ifndef HSE_SEARCH_H
#define HSE_SEARCH_H

#include <string>
#include <vector>
#include <math.h>
#include "hse_common.h"
#include "hse_types.h"
#include "tokenizer.h"

namespace hse {
using std::string;
using std::vector;

class Search {
public:
	//QueryResult is small, so we allow copy construct, and avoid pointer to escape from potential bugs
	struct QueryResult {
		int doc_id;
		vector<int> positions;  //accoring to QueryResults's terms order
		double score;
		int hit_terms; //how many terms are hitted
		vector<const DocPositions*> p_positions;  //DO NOT try to delete the DocPositions*, this is from core place
	};

	struct QueryResults {
		int total; //total documents found in all documents
		int returned;  //returned documents
		long time_used;
		vector<string> terms;
		vector<QueryResult> docs; 
		QueryResults() 
			:time_used(0L){}
	};

	class QueryResultMore: public std::binary_function<QueryResult*, QueryResult*, bool> {
	public:
		bool operator()(QueryResult* q1, QueryResult* q2) {
			return q1->score > q2->score; 
		}
	};

	explicit Search(InvertedList& index);
	/**
	 *search query, and store doc positions int results
	 */
	void RunQuery(string &query, size_t start, size_t count, QueryResults &results);
private:
	InvertedList& index_;

	inline double Score(int doc_id, DocPositions& positions);

	inline double BM25Scorer(int doc_id, DocPositions& positions, size_t ni);
	
	DISALLOW_COPY_AND_ASSIGN(Search);
}; //end of class


} //end of namespace

#endif